package com.im.service.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.ObjUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.SimpleQuery;
import com.im.service.common.ImConstant;
import com.im.service.common.Result;
import com.im.service.common.ServiceException;
import com.im.service.domain.dto.ImChatDTO;
import com.im.service.domain.entity.ImChat;
import com.im.service.domain.entity.ImGroup;
import com.im.service.domain.entity.ImGroupUser;
import com.im.service.domain.entity.ImUser;
import com.im.service.jim.SysSendService;
import com.im.service.mapper.ImGroupMapper;
import com.im.service.mapper.ImGroupUserMapper;
import com.im.service.mapper.ImUserMapper;
import com.im.service.service.ImChatService;
import com.im.service.service.ImGroupUserService;
import org.jim.core.ImChannelContext;
import org.jim.core.packets.Group;
import org.jim.server.JimServerAPI;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * <p>
 * im-群用户 服务实现类
 * </p>
 *
 * @author 刘志强
 * @since 2024-07-03
 */
@Service
public class ImGroupUserServiceImpl extends ServiceImpl<ImGroupUserMapper, ImGroupUser> implements ImGroupUserService {

    @Autowired
    private ImGroupMapper groupMapper;
    @Autowired
    private ImUserMapper userMapper;
    @Autowired
    private ImChatService chatService;
    @Autowired
    private SysSendService sysSendService;

    @Override
    public List<ImGroup> getGroupListByUserId(Long userId) {
        List<Long> groupIds = SimpleQuery.list(
                Wrappers.lambdaQuery(ImGroupUser.class)
                        .eq(ImGroupUser::getUserId, userId),
                ImGroupUser::getGroupId
        );
        if (CollectionUtil.isNotEmpty(groupIds)) {
            List<ImGroup> groupList = groupMapper.selectList(
                    Wrappers.lambdaQuery(ImGroup.class)
                            .in(ImGroup::getId, groupIds)
            );
            return groupList;
        }
        return ListUtil.empty();
    }

    @Override
    public Result batchAddGroupUser(Long groupId, List<Long> userIds) {
        ImGroup imGroup = groupMapper.selectById(groupId);
        if (ObjUtil.isNull(imGroup)) {
            throw new ServiceException("群不存在");
        }
        synchronized (String.valueOf(groupId).intern()) {
            for (Long userId : userIds) {
                if (!ObjUtil.equal(userId, ImConstant.SysUserId)) {
                    this.addGroupUser(imGroup, userId, 2);
                }
            }
        }
        return Result.ok();
    }

    @Override
    public Result<List<ImGroup>> myGroup(Long userId) {
        return Result.okData(getGroupListByUserId(userId));
    }

    @Override
    public void addGroupUser(ImGroup imGroup, Long userId, Integer userType) {
        ImUser imUser = userMapper.selectById(userId);
        ImUser groupLeader = userMapper.selectById(imGroup.getUserId());
        if (ObjUtil.isNotNull(imUser)) {
            // 查询群成员
            ImGroupUser imGroupUser = getOne(Wrappers.lambdaQuery(ImGroupUser.class)
                    .eq(ImGroupUser::getUserId, userId)
                    .eq(ImGroupUser::getGroupId, imGroup.getId())
            );
            if (ObjUtil.isNull(imGroupUser)) {
                // 添加组成员
                imGroupUser = new ImGroupUser();
                imGroupUser.setGroupId(imGroup.getId());
                imGroupUser.setUserId(userId);
                imGroupUser.setUserNickname(imUser.getNickname());
                imGroupUser.setUserType(userType);
                this.save(imGroupUser);

                // 创建会话
                ImChatDTO chatDTO = new ImChatDTO();
                chatDTO.setUserId(userId);
                chatDTO.setType(2);
                chatDTO.setTargetUserId(imGroup.getId());
                chatDTO.setLastMessage("加入群聊");
                chatService.createChat(chatDTO);

                // 绑定组 + 发送系统通知
                List<ImChannelContext> list = JimServerAPI.getByUserId(String.valueOf(userId));
                list.forEach(imChannelContext -> {
                    // 绑定组
                    Group group = Group.newBuilder()
                            .avatar(imGroup.getAvatar())
                            .groupId(String.valueOf(imGroup.getId())).name(imGroup.getGroupName()).build();
                    JimServerAPI.bindGroup(imChannelContext, group);
                });
                // 发送系统通知
                sysSendService.sendToUserId(userId, groupLeader.getNickname() + "创建群组：[" + imGroup.getGroupName() + "]");
            }
        }
    }

    @Override
    public void removeGroupUser(ImGroup imGroup, Long groupUserId, Integer type) {
        ImGroupUser imGroupUser = this.getById(groupUserId);
        ImUser imUser = userMapper.selectById(imGroupUser.getUserId());
        // 移除组员
        this.removeById(groupUserId);
        // 移除会话
        ImChat imChat = chatService.getOne(
                Wrappers.lambdaQuery(ImChat.class)
                        .eq(ImChat::getUserId, imUser.getId())
                        .eq(ImChat::getTargetId, imGroup.getId())
                        .eq(ImChat::getType, 2)
        );
        chatService.removeChat(imChat.getId());


        //解绑定组 + 发送系统通知
        List<ImChannelContext> list = JimServerAPI.getByUserId(String.valueOf(imUser.getId()));
        list.forEach(imChannelContext -> {
            // 解绑组
            JimServerAPI.unbindGroup(String.valueOf(imUser.getId()), String.valueOf(imGroup.getId()));
        });
        // 发送系统通知
        String content = "您被移出群组：[" + imGroup.getGroupName() + "]";
        if (ObjUtil.equals(type, 1)) {
            content = "群组：[" + imGroup.getGroupName() + "]已被解散";
        }
        sysSendService.sendToUserId(imUser.getId(), content);
    }
}
